import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime

# 参数设定
year = 2025
month = 8
del_month = 0
del_years = 0
basic_salary = 8000
PAR = 0.1  # performance_and_other_allowances_rate
social_benefits_rate = 0.02 + 0.08 + 0.005 + 0 + 0 + 0.09
salary_increase_rate = 0.09
inflation_rate = 0.006
MCIR = 0.000292  # Monthly current interest rate
deposit = 3000
housing_fund_rate = 0.18
housing_fund_deposit = 0
PITR_housing_rent = 1000 # Personal income tax refund
PITR = PITR_housing_rent

monthly_housing_deposit = []

# 存储数据用于绘图
dates = []
pretax_pay_data = []  # 税前工资
total_income_data = []  # 总收入(工资+理财)
expense_data = []  # 支出
net_income_data = []  # 净收入
deposit_data = []  # 储蓄
housing_fund_data = []  # 住房公积金


def monthly_life_cost(inner_month, inner_inflation_rate, inner_del_years, inner_del_month):
    company_housing_subsidies = 600
    meal_allowance = 300
    heatstroke_allowance = 150
    gov_housing_subsidies = 600

    room_charge = 1500
    food_expenses = 1500
    miscellaneous_expenses = 180
    travel_expenses = 2*2*30*1.8
    interest_expenses = 360
    base = room_charge + food_expenses + miscellaneous_expenses + travel_expenses + interest_expenses
    if inner_del_month <= 24:
        if inner_del_month <= 12:
            life_cost = base * (1+inner_inflation_rate)**inner_del_years - company_housing_subsidies - meal_allowance - gov_housing_subsidies
        else:
            life_cost = base * (1+inner_inflation_rate)**inner_del_years - gov_housing_subsidies - meal_allowance
    else:
        life_cost = base * (1+inner_inflation_rate)**inner_del_years - meal_allowance
    if inner_month >=6 and inner_month <= 9:
        life_cost = life_cost + heatstroke_allowance
    return life_cost


def income_tax(WPTI):
    if WPTI <= 0:
        return 0
    elif WPTI <= 3000:
        return WPTI * 0.03
    elif WPTI <= 12000:
        return 3000 * 0.03 + (WPTI - 3000) * 0.1
    elif WPTI <= 25000:
        return 3000 * 0.03 + (12000 - 3000) * 0.1 + (WPTI - 12000) * 0.2
    else:
        return 3000 * 0.03 + (12000 - 3000) * 0.1 + (25000 - 12000) * 0.2 + (WPTI - 25000) * 0.25


def month_epoch():
    global year, month, basic_salary, deposit, del_years, del_month, housing_fund_deposit, monthly_housing_deposit

    pretax_pay = basic_salary * (1 + PAR)
    social_security_base_max = 25000
    social_benefits_base = min(pretax_pay, social_security_base_max)
    social_benefits = social_benefits_base * social_benefits_rate

    WPTI = pretax_pay - social_benefits - 5000 - PITR  # Withholding and prepayment of taxable income
    individual_income_tax = income_tax(WPTI)
    monthly_income = pretax_pay - social_benefits - individual_income_tax

    monthly_outcome = monthly_life_cost(month, inflation_rate, del_years, del_month)
    monthly_financial_income = deposit * MCIR
    total_income = monthly_income + monthly_financial_income  # 可支配收入
    monthly_net_income = total_income - monthly_outcome
    deposit = deposit + monthly_net_income
    monthly_housing_deposit.insert(0, housing_fund_rate * pretax_pay)
    monthly_housing_deposit = [monthly_housing_deposit[i]*(1+30*i*0.015/360) for i in range(len(monthly_housing_deposit))]
    housing_fund_deposit = sum(monthly_housing_deposit)

    # 记录数据用于绘图
    dates.append(datetime(year, month, 1))
    pretax_pay_data.append(pretax_pay)
    total_income_data.append(total_income)
    expense_data.append(monthly_outcome)
    net_income_data.append(monthly_net_income)
    deposit_data.append(deposit)
    housing_fund_data.append(housing_fund_deposit)

    print(f'{year}年{month}月，税前工资={pretax_pay:.2f}，可支配收入={total_income:.2f}，支出={monthly_outcome:.2f}，\
    当月净收入={monthly_net_income:.2f}，储蓄={deposit:.2f}，住房公积金储蓄={housing_fund_deposit:.2f}')

    month = month + 1
    del_month = del_month + 1
    if month == 13:
        month = 1
        year = year + 1
        del_years = del_years + 1

    if month == 8 and del_years > 0:
        basic_salary = basic_salary * (1 + salary_increase_rate)


def main():
    while (year < 2028) or (year == 2028 and month <= 7):
        month_epoch()

    print(f'三年可支配总收入 = {sum(total_income_data):.2f}')
    print(f'三年总支出 = {sum(expense_data):.2f}')
    print(f'三年总储蓄 = {(deposit + housing_fund_deposit):.2f}')
    saving_rate = (deposit + housing_fund_deposit) / sum(total_income_data)
    print(f'储蓄率 = {saving_rate:.4f}')

    # 绘制图表
    plt.figure(figsize=(12, 8))

    # 设置日期格式
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=3))

    # 绘制各项数据曲线
    plt.plot(dates, pretax_pay_data, 'ro-', label='pretax_pay_data')
    plt.plot(dates, total_income_data, 'go-', label='total_income_data')
    plt.plot(dates, expense_data, 'bo-', label='expense_data')
    plt.plot(dates, net_income_data, 'mo-', label='net_income_data')

    # 添加标题和标签
    plt.title('income and outcome', fontsize=16)
    plt.xlabel('date', fontsize=12)
    plt.ylabel('money', fontsize=12)
    plt.grid(True, linestyle='--', alpha=0.7)
    plt.legend(loc='upper left')

    # 旋转x轴标签以避免重叠
    plt.gcf().autofmt_xdate()

    # 显示图表
    plt.tight_layout()
    plt.savefig('income_expense_trends.png', dpi=300)
    plt.show()

    # 单独绘制储蓄曲线（因为数值差异较大）
    plt.figure(figsize=(12, 6))
    plt.plot(dates, deposit_data, 'c^-', label='deposit')
    plt.plot(dates, housing_fund_data, 'r^-', label='housing_fund_deposit')
    plt.title('deposit', fontsize=16)
    plt.xlabel('date', fontsize=12)
    plt.ylabel('money', fontsize=12)
    plt.grid(True, linestyle='--', alpha=0.7)
    plt.legend(loc='upper left')
    plt.gcf().autofmt_xdate()
    plt.tight_layout()
    plt.savefig('savings_trend.png', dpi=300)
    plt.show()


if __name__ == "__main__":
    main()
